home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / RCSC.ZIP / PACKAGES / AWK320.ZIP / M1.AWK < prev    next >
Text File  |  1990-06-13  |  4KB  |  139 lines

  1. # From Jon Bentley's article in Computer Language June '90 (v7n6)
  2. # LISTING 4
  3.  
  4. function error(s) {
  5.  
  6.     print "m1: " s >"CON"                                               #
  7.     exit 1
  8. }
  9.  
  10. function dofile(fname, savefile, savebuffer, newstring) {
  11.  
  12.     if (fname in activefiles)
  13.         error("recursively reading file: " fname)
  14.     activefiles[fname] = 1
  15.     savefile = file
  16.     file = fname
  17.     savebuffer = buffer
  18.     buffer = ""
  19.     while (readline() != EOF) {
  20.         if (index($0, "@") == 0) {
  21.             print $0
  22.         }
  23.         else if ($0 ~ /^@define[ \t]/) {
  24.             dodef(1)                                                    #
  25.         }
  26.         else if ($0 ~ /^@default[ \t]/) {
  27.             dodef(0)                                                    #
  28.         }
  29.         else if ($0 ~ /^@include[ \t]/) {
  30.             if (NF != 2) error("bad inlcude line")
  31.             dofile(dosubs($2))
  32.         }
  33.         else if ($0 ~ /^@if[ \t]/) {
  34.             if (NF != 2) error("bad if line")
  35.             if (!($2 in symtab) || symtab[$2] == 0) gobble()
  36.         }
  37.         else if ($0 ~ /^@unless[ \t]/) {
  38.             if (NF != 2) error("bad unless line")
  39.             if (($2 in symtab) && symtab[$2] != 0) gobble()
  40.         }
  41.         else if ($0 ~ /^@fi[ \t]?/) {    # could do error checking
  42.         }
  43.         else if ($0 ~ /^@comment[ \t]?/) {
  44.         }
  45.         else {
  46.             newstring = dosubs($0)
  47.             if ($0 == newstring || index(newstring, "@") == 0)
  48.                 print newstring
  49.             else
  50.                 buffer = newstring "\n" buffer
  51.         }
  52.     }
  53.     close(fname)
  54.     delete activefiles[fname]
  55.     file = savefile
  56.     buffer = savebuffer
  57. }
  58.  
  59. function readline(      i, status) {
  60.  
  61.     status = ""
  62.     if (buffer != "") {
  63.         i = index(buffer, "\n")
  64.         $0 = substr(buffer, 1, i - 1)
  65.         buffer = substr(buffer, i + 1)
  66.     }
  67.     else {
  68.         if (file == "-") {                                              #
  69.             i = getline                                                 #
  70.         }                                                               #
  71.         else {                                                          #
  72.             i = getline < file                                          #
  73.         }                                                               #
  74.         status = i <= 0 ? "EOF" : ""                                    #
  75.     }
  76.     return status
  77. }
  78.  
  79. function gobble(        ifdepth) {
  80.  
  81.     ifdepth = 1
  82.     while (readline()) {
  83.         if ($0 ~ /^@(if|unless)[ \t]/) ifdepth++
  84.         if ($0 ~ /^@fi[ \t]?/ && --ifdepth <= 0) break
  85.     }
  86. }
  87.  
  88. function dosubs(s,      l, r, i, m) {
  89.  
  90.     if (index(s, "@") == 0) return s
  91.     l = ""  # Left of current pos: ready for output
  92.     r = s   # Right of current: unexamined at this time
  93.     while ((i = index(r, "@")) != 0) {
  94.         l = l substr(r, 1, i - 1)
  95.         r = substr(r, i + 1)            # Currently scanning @
  96.         i = index(r, "@")
  97.         if (i == 0) {
  98.             l = l "@"
  99.             break
  100.         }
  101.         m = substr(r, 1, i - 1)
  102.         r = substr(r, i + 1)
  103.         if (m in symtab) {
  104.             r = symtab[m] r
  105.         }
  106.         else {
  107.             l = l "@" m
  108.             r = "@" r
  109.         }
  110.     }
  111.     return l r
  112. }
  113.  
  114. function dodef(def,     str, name) {
  115.  
  116.     name = $2
  117.     sub(/^[ \t]*[^ \t]+[ \t]+[^ \t]+[ \t]+/, "")    # $0=$P($0,FS,3,NF)
  118.     str = $0
  119.     while (str ~ /\\$/) {
  120.         if (readline() == EOF)
  121.             error("EOF inside definition")
  122.         sub(/^[ \t]+/, "")
  123.         sub(/[ \t]*\\$/, "\n" $0, str)
  124.     }
  125.     if (def || !(name in symtab))                                       #
  126.         symtab[name] = str
  127. }
  128.  
  129. BEGIN {
  130.  
  131.     EOF = "EOF"
  132.     if (ARGC == 1) dofile("-")                                          #
  133.     else if (ARGC == 2) dofile(ARGV[1])
  134.     else {
  135.         print "Usage: m1 [file]" >"CON"                                 #
  136.         exit
  137.     }
  138. }
  139.